/*
 * copyright (c) 2009 Alexandr [Sn@ble] Surnin
 *
 * This file is part of FrameSeeker.
 *
 * FrameSeeker is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FrameSeeker is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You can read the full version of GNU LGPL in
 * http://www.gnu.org/copyleft/lesser.html
 */


#ifndef FSFFMPEG_H
#define FSFFMPEG_H

// including "Pure C" FSffmpeg libs
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/avutil.h>
#include <libswscale/swscale.h>
}


#include <QString>
#include <QList>
#include <QSettings>
#include <QTime>

#include "FSDefines.h"
#include "FSFrame.h"



/** Video\Audio codecs class
  * Exporting frame data
  * \author Alexandr [Sn@ble] Surnin
  */
class FSffmpeg : public QObject {
    Q_OBJECT

public: // methods
    FSffmpeg();
    ~FSffmpeg();


    /** Open specific video file
      * \param _fileName Name of the file
      * \sa createFrames(), createSwsContexts
      * \note After open file you must to run
      * createFrames() and after it -
      * createSwsContexts() methods
      * \return Error code (0 == OK)
      */
    int openFile(QString _fileName);


    /** Get the loaded movie frame rate per second
      * \return Frame rate in "frames per second"
      */
    float getFrameRate();


    /** Get a type of frame
      \return Frame type
      * 1 == "I" Intra frame
      * 2 == "P" Predictional frame
      * 3 == "B" Bidirection predictional frame
      * 4 == "S" Sprite
      * 5 == "SI"
      * 6 == "SP"
      * 7 == "BI"
      */
    int getFrameType();


public slots: // slots
    /** Read frame from the video stream
      * \return Error code (0 == OK)
      */
    int readFrame();


    /** Jump to frame
      * \param _frameIndex Frame index
      */
    void seekFrame(int _frameIndex);


    void readSettings(QSettings *settings);


signals: // signals

    /** Send RGB frame with motion vectors and sizes
      * \param _frame Frame
      */
    void sendFrame(FSFrame *_frame);

private: // methods

    /** Allocate memory for frames
      * \sa openFile(), createSwsContext()
      * \return Error code (0 == OK)
      */
    int createFrames();


    /** Allocate memory for scaling contexts
      * \return Error code (0 == OK)
      */
    int createSwsContexts();

private: // data
    uint8_t* buffer;
    QString fileName;
    AVFormatContext *fmtCtx;
    AVCodecContext *codecCtx;
    AVCodec *codec;
    AVFrame *frameYUV; // YUV means YCrCb
    AVFrame *frameRGB;
    SwsContext *toTarget;
    int videoStreamIndex;
    int audioStreamIndex;

    PixelFormat target_pix_fmt;
    PixelFormat orig_pix_fmt;
    int imgWidth;
    int imgHeight;
    float frameRate;
    int frameIndex;

    int stop;

    FSFrame *frame;

};

#endif // FSFFMPEG_H
